package org.redis.cluster.transport;

import org.redis.cluster.RedisCluster;
import org.redis.cluster.config.ServerConfig;
import org.redis.cluster.extension.ExtensionLoader;
import org.redis.cluster.plugin.Plugin;
import org.redis.cluster.transport.protocol.ProtocolDecoder;
import org.redis.cluster.transport.protocol.ProtocolEncoder;
import org.redis.cluster.transport.server.Server;
import org.redis.cluster.transport.server.ServerFactory;
import org.redis.cluster.transport.session.SessionProcessor;
import org.redis.cluster.util.Assert;

public class DefaultServerFactory implements Plugin,ServerFactory {
	
	private final static String DEFAULT_PROTOCOL_DECODER="serverDecoder";
	
	private final static String DEFAULT_PROTOCOL_ENCODER="serverEncoder";
	
	private final static String DEFAULT_SESSION_PROCESSOR="serverSessionProcessor";
	
	private RedisCluster redisCluster;
	private ExtensionLoader extensionLoader; 
	private ProtocolDecoder decoder;
	private ProtocolEncoder encoder;
	private SessionProcessor<?> processor;

	@Override
	public void init(RedisCluster redisCluster) {
		this.redisCluster=redisCluster;
		this.extensionLoader=redisCluster.getExtensionLoader();
		
		this.decoder=initDecoder();
		Assert.notNull(decoder,"decoder不能为空");
		
		this.encoder=initEncoder();
		Assert.notNull(decoder,"encoder不能为空");
		
		this.processor=initProcessor();
		Assert.notNull(processor,"processor不能为空");
	}
	
	@Override
	public void destroy() {
	}
	
	@Override
	public Server getServer(ServerConfig serverConfig) {
		Server server=getServer(serverConfig, decoder, encoder,processor);
		Assert.notNull(server,"server不能为空");
		
		return server;
	}
	
	protected Server getServer(ServerConfig config,ProtocolDecoder decoder,ProtocolEncoder encoder,SessionProcessor<?> sessionProcessor) {
		return extensionLoader.load(config.getServer(), Server.class, config,decoder,encoder,sessionProcessor);
	}
	
	protected ProtocolDecoder initDecoder() {
		return extensionLoader.load(DEFAULT_PROTOCOL_DECODER, ProtocolDecoder.class);
	}
	
	protected ProtocolEncoder initEncoder() {
		return extensionLoader.load(DEFAULT_PROTOCOL_ENCODER, ProtocolEncoder.class);
	}
	
	protected SessionProcessor<?> initProcessor() {
		return extensionLoader.load(DEFAULT_SESSION_PROCESSOR,SessionProcessor.class);
	}
}